<template>
    <div class="excel-container">
        <div class="toolbar">
            <input type="file" accept=".xlsx,.xls" @change="handleFileUpload" ref="fileInput" hidden />
            <button class="custom-button" @click="fileInput?.click()">
                选择Excel文件
            </button>
            <button @click="showGrid = !showGrid" :class="['custom-button', { active: showGrid }]">
                {{ showGrid ? '隐藏网格' : '显示网格' }}
            </button>
            <button class="custom-button" @click="mergeCells">
                合并单元格
            </button>
            <button class="custom-button" @click="splitCells">
                拆分单元格
            </button>
        </div>

        <div class="table-wrapper">
            <table :style="{ border: showGrid ? '1px solid #ddd' : '1px solid transparent' }">
                <thead>
                    <tr>
                        <th class="row-header"></th>
                        <th v-for="col in columns" :key="col.key"
                            :style="{ border: showGrid ? '1px solid #ddd' : '1px solid transparent' }">
                            {{ col.title }}
                        </th>
                    </tr>
                </thead>
                <tbody>
                    <tr v-for="(row, rowIndex) in tableData" :key="rowIndex">
                        <td class="row-header"
                            :style="{ border: showGrid ? '1px solid #ddd' : '1px solid transparent' }">
                            {{ row.__rowNum__ }}
                        </td>
                        <td v-for="(col, colIndex) in columns" :key="col.key" :style="{
                border: showGrid ? '1px solid #ddd' : '1px solid transparent',
                display: shouldHideCell(rowIndex, colIndex) ? 'none' : 'table-cell'
            }" :rowspan="getRowspan(rowIndex, colIndex)" :colspan="getColspan(rowIndex, colIndex)"
                            :class="{ selected: isCellSelected(rowIndex, colIndex) }"
                            @click="handleCellClick(rowIndex, colIndex, $event)"
                            @dblclick="startEditCell(rowIndex, colIndex)"
                            @mousedown="startDragSelection(rowIndex, colIndex)"
                            @mouseover="updateDragSelection(rowIndex, colIndex)"
                            @contextmenu.prevent="handleContextMenu($event, rowIndex, colIndex)">

                            <input ref="cellInput" type="text" v-model="row[col.key]"
                                :class="{ 'cell-border': showGrid }" :readonly="!isEditing(rowIndex, colIndex)" />
                        </td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>
    <div v-if="showContextMenu" class="context-menu"
        :style="{ left: contextMenuPosition.x + 'px', top: contextMenuPosition.y + 'px' }">
        <div class="context-menu-item" @click="copyCells">复制</div>
        <div class="context-menu-item" @click="pasteCells">粘贴</div>
    </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onBeforeUnmount, nextTick } from 'vue'
// @ts-ignore
import * as XLSX from 'xlsx'

// 添加文件输入引用声明
const fileInput = ref<HTMLInputElement | null>(null)

interface ExcelRow {
    [key: string]: any
}

const editingCell = ref({ row: -1, col: -1 })
const isDragging = ref(false)
const contextMenuPosition = ref({ x: 0, y: 0 })
const showContextMenu = ref(false)
// 添加编辑状态判断方法
const isEditing = (row: number, col: number) => {
    return editingCell.value.row === row && editingCell.value.col === col
}
const tableData = ref<ExcelRow[]>([])
const columns = ref<any[]>([])
const showGrid = ref(true)
const selectedRange = ref({
    startRow: -1,
    startCol: -1,
    endRow: -1,
    endCol: -1
})

// 合并单元格功能
const mergeCells = () => {
    // 实现合并逻辑，将选择的单元格合并成一个单元格
    // 获取选择范围
    const { startRow, startCol, endRow, endCol } = selectedRange.value
    const minRow = Math.min(startRow, endRow)
    const maxRow = Math.max(startRow, endRow)
    const minCol = Math.min(startCol, endCol)
    const maxCol = Math.max(startCol, endCol)

    // 有效性检查（至少选择两个单元格）
    if (minRow === maxRow && minCol === maxCol) {
        alert('请选择多个单元格进行合并')
        return
    }

    // 创建合并记录
    const newMerge = {
        s: { r: minRow, c: minCol },
        e: { r: maxRow, c: maxCol }
    }

    // 更新单元格合并状态
    tableData.value = tableData.value.map((row, rowIndex) => {
        if (rowIndex >= minRow && rowIndex <= maxRow) {
            return {
                ...row,
                __merges__: row.__merges__ ? [...row.__merges__, newMerge] : [newMerge]
            }
        }
        return row
    })

    console.log('合并区域：', newMerge)
}

// 拆分单元格功能
const splitCells = () => {
    // 实现拆分逻辑
    console.log('执行拆分操作')
}

const handleFileUpload = (e: Event) => {
    const file = (e.target as HTMLInputElement).files?.[0]
    if (!file) return

    const reader = new FileReader()
    reader.onload = (e) => {
        const data = new Uint8Array(e.target?.result as ArrayBuffer)
        const workbook = XLSX.read(data, { type: 'array' })
        const worksheet = workbook.Sheets[workbook.SheetNames[0]]
        const range = XLSX.utils.decode_range(worksheet['!ref']!)
        const colCount = range.e.c + 1

        // 生成列配置
        columns.value = [...Array(colCount)].map((_, index) => ({
            title: String.fromCharCode(65 + index),
            key: `col${index}`
        }))

        // 生成表格数据
        const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 })
        tableData.value = jsonData.slice(1).map((row: any, rowIndex) => {
            return [...Array(colCount)].reduce((acc, _, colIndex) => {
                acc[`col${colIndex}`] = row[colIndex] ?? ''
                acc.__rowNum__ = rowIndex + 1
                return acc
            }, {} as ExcelRow)
        })
    }
    reader.readAsArrayBuffer(file)
}

// 单击选择单元格
const handleCellClick = (row: number, col: number, e: MouseEvent) => {
    // 如果是当前编辑单元格且点击的是输入框，则允许光标移动
    if (isEditing(row, col) && (e.target as HTMLElement).tagName === 'INPUT') {
        return
    }

    // 非当前编辑单元格时执行选择
    if (!isEditing(row, col)) {
        editingCell.value = { row: -1, col: -1 }
        selectedRange.value = {
            startRow: row,
            startCol: col,
            endRow: row,
            endCol: col
        }
    }
}

//双击编辑单元格
const startEditCell = (row: number, col: number) => {
    editingCell.value = { row, col }
    nextTick(() => {
        const input = document.querySelector(`[data-row="${row}"][data-col="${col}"] input`) as HTMLInputElement
        input?.focus()
    })
}

// 拖动选择
const startDragSelection = (row: number, col: number) => {
    isDragging.value = true
    selectedRange.value = {
        startRow: row,
        startCol: col,
        endRow: row,
        endCol: col
    }
}

const updateDragSelection = (row: number, col: number) => {
    if (isDragging.value) {
        selectedRange.value.endRow = row
        selectedRange.value.endCol = col
    }
}

// 右键菜单
const handleContextMenu = (event: MouseEvent, row: number, col: number) => {
    contextMenuPosition.value = { x: event.clientX, y: event.clientY }
    showContextMenu.value = true
    handleCellClick(row, col, event)
}

// 复制粘贴功能
const copyCells = () => {
    // 实现复制逻辑
    console.log('复制单元格', selectedRange.value)
    showContextMenu.value = false
}

const pasteCells = () => {
    // 实现粘贴逻辑
    console.log('粘贴单元格', selectedRange.value)
    showContextMenu.value = false
}

// 判断单元格是否被隐藏
const shouldHideCell = (row: number, col: number) => {
    return tableData.value[row]?.__merges__?.some(merge =>
        row > merge.s.r && row <= merge.e.r ||
        col > merge.s.c && col <= merge.e.c
    )
}

// 获取行跨度
const getRowspan = (row: number, col: number) => {
    const merge = tableData.value[row]?.__merges__?.find(m =>
        m.s.r === row && m.s.c === col
    )
    return merge ? merge.e.r - merge.s.r + 1 : 1
}

// 获取列跨度
const getColspan = (row: number, col: number) => {
    const merge = tableData.value[row]?.__merges__?.find(m =>
        m.s.r === row && m.s.c === col
    )
    return merge ? merge.e.c - merge.s.c + 1 : 1
}

// 添加鼠标抬起事件监听
document.addEventListener('mouseup', () => {
    isDragging.value = false
})

document.addEventListener('click', (e) => {
    if (!(e.target as HTMLElement).closest('.context-menu')) {
        showContextMenu.value = false
    }
})

const isCellSelected = (row: number, col: number) => {
    const { startRow, startCol, endRow, endCol } = selectedRange.value
    const minRow = Math.min(startRow, endRow)
    const maxRow = Math.max(startRow, endRow)
    const minCol = Math.min(startCol, endCol)
    const maxCol = Math.max(startCol, endCol)

    return row >= minRow &&
        row <= maxRow &&
        col >= minCol &&
        col <= maxCol
}
</script>

<style scoped>
.context-menu {
    position: fixed;
    background: white;
    border: 1px solid #ddd;
    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.1);
    z-index: 10000;
    min-width: 120px;
}

.context-menu-item {
    padding: 8px 16px;
    cursor: pointer;

    &:hover {
        background: #f5f5f5;
    }
}

input:read-only {
    background: transparent;
    cursor: default;
}

.excel-container {
    height: 100%;
    padding: 12px;
    display: flex;
    flex-direction: column;
}

.toolbar {
    margin-bottom: 12px;
    display: flex;
    gap: 8px;
}

.custom-button {
    padding: 8px 16px;
    border: 1px solid #ddd;
    border-radius: 4px;
    background: #f5f5f5;
    color: #333;
    cursor: pointer;
    transition: all 0.2s;
    font-size: 14px;
    line-height: 1;
    display: inline-flex;
    align-items: center;
}

/* 移除原生按钮的默认样式 */
button.custom-button {
    appearance: none;
    outline: none;
}

.custom-button:hover {
    background: #e8e8e8;
}

.custom-button.active {
    background: #409eff;
    color: white;
}

.table-wrapper {
    flex: 1;
    overflow: auto;
    border: 1px solid #ddd;
    /* 添加最小高度保证滚动容器有效性 */
    min-height: 300px;
}

/* 合并重复的th样式定义 */
th {
    background: #fafafa;
    position: sticky;
    top: 0;
    z-index: 1000;
    box-shadow: 0 2px 2px -1px rgba(0, 0, 0, 0.1);
    padding: 8px;
    min-width: 120px;
}

.row-header {
    background: #f5f5f7;
    width: 60px;
    position: sticky;
    left: 0;
    z-index: 1001;
    border: 1px solid transparent;

}

table {
    width: 100%;
    border-collapse: collapse;
    background: white;
    border-spacing: 0;
}

th,
td {
    padding: 0px;
    min-width: 120px;
    border-width: 1px;
}

th {
    background: #fafafa;
    position: sticky;
    top: 0;
    z-index: 1;
}

.row-header {
    background: #f5f5f7;
    width: 60px;
    position: sticky;
    left: 0;
    z-index: 2;
}

input {
    width: 100%;
    height: 100%;
    border: none;
    padding: 2px;
    background: transparent;
    box-sizing: border-box;
    margin: 0;
    outline: none;
}

input:focus {
    border: 1px solid black;
}

input:read-only:focus {
    border: none;
}

/* 新增单元格容器样式 */
td {
    position: relative;
    padding: 0 !important;
}

td.selected {
    background: rgba(64, 158, 255, 0.2) !important;
}

td>input {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
}

/* 新增单元格通用边框控制 */
th:not(.row-header),
td:not(.row-header) {
    border: 1px solid transparent;
}
</style>